package com.moli.iov.handle.alarm.biz.real.extend.platform;

import com.moli.iov.cache.RedisUtil;
import com.moli.iov.handle.alarm.constants.AlarmMemoConstant;
import com.moli.iov.handle.alarm.constants.Constant;
import com.moli.iov.handle.alarm.enums.AlarmCodeEnum;
import com.moli.iov.handle.alarm.enums.AlarmSourceEnum;
import com.moli.iov.handle.alarm.enums.AntiShakeEnum;
import com.moli.iov.handle.alarm.enums.CheckAlarmEnum;
import com.moli.iov.handle.alarm.model.dto.AlarmDto;
import com.moli.iov.handle.alarm.service.IAlarmInfoRequestService;
import com.moli.iov.protocol.model.realtime.RealTimeInfoReq;
import com.moli.iov.util.StringUtil;
import java.util.Date;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * <p>
 *  里程异变报警
 * </p>
 *
 * @author: zql
 * @Date: 2019/4/28 11:31
 */
@Slf4j
@Component
public class MileageExceptionChangeReal {

    @Autowired
    private IAlarmInfoRequestService alarmInfoRequestService;
    @Autowired
    private RedisUtil redisUtil;

    @Value("${mil_ex_threshold}")
    private double milExThreshold;

   public void handle(RealTimeInfoReq realTimeInfoReq){
        try{

            String collectDate =
                    realTimeInfoReq.getCollectDate() != null ? realTimeInfoReq.getCollectDate().toString() : "";
            if(realTimeInfoReq.getVehicleAllReq() == null){
                log.error("里程异变报警 失败，VehicleAllReq空 vin:{} 数据采集时间：{}",
                        realTimeInfoReq.vin, collectDate);
                return;
            }

            subHandle(realTimeInfoReq.vin, realTimeInfoReq);
        }catch(Exception e){
            log.error("里程异变报警 异常", e);
        }
    }

    /**
     * 里程异变报警
     * @param vin
     * @param realTimeInfoReq
     */
    public void subHandle(String vin, RealTimeInfoReq realTimeInfoReq){

        double mileage = realTimeInfoReq.vehicleAllReq.getOdometer();
        if(mileage <=0 ){
            return;
        }

        double lastTimeMileage = getLastTimeMileage(vin);
        setLastTimeMileage(vin,  mileage);
        double differenceMileage = lastTimeMileage - mileage;
        //报警
        if(lastTimeMileage > mileage && differenceMileage > milExThreshold){

          log.info("[里程异变报警] [报警] vin:{} 上一次累计里程: {} 当前里程：{} 数据采集时间：{}",
                  vin, lastTimeMileage, mileage, getCollectDate(realTimeInfoReq));

          alarmInfoRequestService.alarm(assembleDto(vin, realTimeInfoReq,
                              lastTimeMileage, mileage, differenceMileage));
        }
    }

  /**
   * 组装dto
   * @param vin
   * @param realTimeInfoReq
   * @param lastTimeMileage
   * @param currentMileage
   * @param differenceMileage
   * @return
   */
    public AlarmDto assembleDto(String vin, RealTimeInfoReq realTimeInfoReq,
                                      double lastTimeMileage, double currentMileage, double differenceMileage){

      double longitude = realTimeInfoReq.vehicleGpsReq != null ?
          realTimeInfoReq.vehicleGpsReq.longitude : 0;
      double latitude = realTimeInfoReq.vehicleGpsReq != null ?
          realTimeInfoReq.vehicleGpsReq.latitude : 0;
      String memo = AlarmMemoConstant.MILE_EX_CHANGE_MEMO
          .replaceAll("@1", String.valueOf(lastTimeMileage));
      memo = memo.replaceAll("@2", String.valueOf(currentMileage));
      Date collectDate = realTimeInfoReq.getCollectDate() != null ?
          realTimeInfoReq.getCollectDate().getDate() : null;

      AlarmDto alarmDto = new AlarmDto();
      alarmDto.setVin(vin);
      alarmDto.setAlarmCode(AlarmCodeEnum.MILEAGE_EXCEPTION_CHANGE.getFlag());
      alarmDto.setAlarmLevel(AlarmCodeEnum.MILEAGE_EXCEPTION_CHANGE.getLevel());
      alarmDto.setAlarmType(AlarmSourceEnum.PLATFORM.getFlag());
      alarmDto.setIsAntiShake(AntiShakeEnum.NO.getFlag());
      alarmDto.setLongitude(longitude);
      alarmDto.setLatitude(latitude);
      alarmDto.setLastTimeMileage(lastTimeMileage);
      alarmDto.setCurrentMileage(currentMileage);
      alarmDto.setDifferenceMileage(differenceMileage);
      alarmDto.setMilExThreshold(milExThreshold);
      alarmDto.setMemo(memo);
      alarmDto.setIsCheckAlarming(CheckAlarmEnum.NO.isFlag());
      alarmDto.setCollectDate(collectDate);

      return alarmDto;
    }

    /**
     * 获取上一次累计里程
     * @param vin
     * @return
     */
    public double getLastTimeMileage(String vin){
        String s = redisUtil.get(getLastTimeMileageKey(vin));
        if(StringUtil.isBlank(s)){
            return 0;
        }
        return Double.parseDouble(s);
    }

    /**
     * 设置最新的累计里程
     * @param vin
     * @param melieage
     */
    public void setLastTimeMileage(String vin, double melieage){
        redisUtil.set(getLastTimeMileageKey(vin), String.valueOf(melieage));
    }

    /**
     * monitor enter
     * monitor
     * monitor exit
     * 获取上一次累计里程缓存key
     * @param vin
     * @return
     */
    public String getLastTimeMileageKey(String vin){
        return Constant.VIN_LAST_TIME_MILEAGE + vin;
    }

  /**
   * 获取上报时间
   * @param realTimeInfoReq
   * @return
   */
  public String getCollectDate(RealTimeInfoReq realTimeInfoReq){
    return realTimeInfoReq.getCollectDate() != null ? realTimeInfoReq.getCollectDate().toString() : "";
  }
}
